package sysu.el.graph;

import sysu.el.array.ints.ArrInt;

public abstract class GTAdjList implements GTInterface{

	/* ******************************************************************** */
	/* ************************* Attribute op ***************************** */
	/* ******************************************************************** */
	public ArrInt[] adjNodes;
	protected int edgeNum;

	//	public static GTAdjList wrap(int[][] a) {
	//		MutateAdjList gta = new MutateAdjList();
	//		gta.counter = new int[a.length];
	//		for (int i=0; i<a.length; i++){
	//			gta.counter[i] = a[i].length;
	//		}
	//		gta.adjNodes = a;
	//		return gta;
	//	}

	/* ******************************************************************** */
	/* ************************* Constructors ***************************** */
	/* ******************************************************************** */
	public GTAdjList(int nodeNum){
		edgeNum = 0;
		adjNodes = new ArrInt[nodeNum];
		for (int i=0; i < nodeNum; i++)
			adjNodes[i] = new ArrInt(nodeNum);
	}

	public GTAdjList(GTMatrix matrix){
		edgeNum = 0;
		int nodeNum = matrix.getNodeNum();
		adjNodes = new ArrInt[nodeNum];
		for (int i=0; i < nodeNum; i++)
			adjNodes[i] = new ArrInt(nodeNum);
	}

	protected GTAdjList(){};

	/* ******************************************************************** */
	/* ************************* Essential OP ***************************** */
	/* ******************************************************************** */
	public int getDegree(int i){
		return adjNodes[i].counter;
	}
	
	//-TODO: Picture this scene, list is n-size but with k filled
	// Terrible error.
	public int[] getList(int i){
		return adjNodes[i].elements();
	}
	
	public ArrInt getAdjNodes(int i){
		return adjNodes[i];
	}
	
	protected void addEdgePrimitive(int i, int j){
		adjNodes[i].add(j);
	}
	
	/* ******************************************************************** */
	/* ************************* Interface OP ***************************** */
	/* ******************************************************************** */

	public int getNodeNum(){
		return adjNodes.length;
	}

	public int getEdgeNum(){
		return this.edgeNum;
	}
	
	public int getW(int i, int j){
		int c = getDegree(i);
		int [] list = getList(i);
		for (int k=0; k<c; k++)
			if (j == list[k])
				return 1;
		
		return 0;
	}

	public int getVal(int i, int j){
		if (j < getDegree(i))
			return 1;
		else return 0;
	}
	
	public abstract void addEdge(int i, int j);

}
